package com.ebs.md.fxmonitor.marketmonitor;

/**
 * Perforce Revision:
 *  $File: //depot/MarketData/fxmonitor/main/src/main/java/com/ebs/md/fxmonitor/marketmonitor/AbstractEventMessageCreator.java $
 *  $Revision: #8 $  $Change: 115040 $  $DateTime: 2012/09/19 13:09:38 $  $Author: Arik.Sher $
 */

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.apache.log4j.Logger;
import org.springframework.util.Assert;

import com.ebs.commons.comp.IParsedPayload;
import com.ebs.market.monitor.MarketMonitor.EventType;
import com.ebs.market.monitor.jms.MarketMonitorJmsConsts;
import com.ebs.md.fxmonitor.marketmonitor.AbstractMonitorListenerAndPublisher.EventMessageCreator;
import com.google.protobuf.MessageLite;


public abstract class AbstractEventMessageCreator<GPB extends MessageLite>
implements EventMessageCreator
          ,MarketMonitorJmsConsts
          ,MarketMonitorConsts
{
    final protected Logger logger = Logger.getLogger(getClass());

    protected IParsedPayload payload;
	protected final long  eventTimeMillis;
	
	public AbstractEventMessageCreator(IParsedPayload payload) {
		super();
		Assert.notNull(payload, "'payload' cannot be null");
		this.payload = payload;
		this.eventTimeMillis = System.currentTimeMillis();
	}

	public Message createMessage(Session session) throws JMSException {
		GPB eventObj = createEventObject(payload);
		
		BytesMessage jmsMessage = session.createBytesMessage();
		jmsMessage.writeBytes(eventObj.toByteArray());
		
		appendProperties(jmsMessage);
		
		jmsMessage.reset();
		return jmsMessage;
	}

	protected void appendProperties(Message jmsMessage) throws JMSException {
		jmsMessage.setIntProperty(   JMS_MSG_PROPERTY_EVENT_TYPE
				, getEventType().getNumber());

		jmsMessage.setStringProperty(JMS_MSG_PROPERTY_BASE_CURRENCY_ISO
				,payload.getParsedStringField( "base_ccy_iso"));
		jmsMessage.setStringProperty(JMS_MSG_PROPERTY_LOCAL_CURRENCY_ISO
				,payload.getParsedStringField("local_ccy_iso"));
		
		doAppendExtraProperties(jmsMessage);
	}
	
	protected void doAppendExtraProperties(Message jmsMessage) throws JMSException {
		// nothing here, this method is used for override... 
	}

	protected String genEventId(String quoteId, long actionTimeMillis) {
		final EventType eventType = getEventType();
		final String truncatedToDate = truncateToDate(actionTimeMillis);
		
		String val = 
			String.format("%d#%s#%s"
				,eventType.getNumber()
				,quoteId
				,truncatedToDate
			);
		
		return val;
	}
	
	final protected static TimeZone gmtTZ = TimeZone.getTimeZone("GMT");
	
	/**
	 * 
	 * @param millis since 1970
	 * @return "yyyymmdd"
	 */
	protected static String truncateToDate(long millis) {
		final Calendar cal = Calendar.getInstance(gmtTZ);
		cal.setTimeInMillis(millis);
		
//		final Calendar truncated = DateUtils.truncate(cal, Calendar.DAY_OF_MONTH);
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		sdf.setTimeZone(gmtTZ);
		
		return sdf.format(cal.getTime());
	}
	
	abstract protected GPB createEventObject(IParsedPayload payload);

	abstract public EventType getEventType();
	
}
